home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************/
- /* trans.c */
- /* */
- /* Transformations of rays, hits, planes, and bounding boxes */
- /* Modified from Optik v(1.2e) (C) 1987 John Amanatides & Andrew Woo */
- /* */
- /* Copyright (C) 1992, Bernard Kwok */
- /* All rights reserved. */
- /* Revision 1.0 */
- /* May, 1992 */
- /**********************************************************************/
- #include <stdio.h>
- #include "geo.h"
- #include "misc.h"
- #include "struct.h"
- #include "ray.h"
-
- /**********************************************************************/
- void RayTransform();
- Plane PlaneTransform();
- void HitTransform();
- BoundingBoxType BoundingBoxTransform();
-
- /**********************************************************************/
- /* Transform a ray */
- /**********************************************************************/
- void RayTransform(old, new, m)
- register Ray *old, *new;
- register Matrix m;
- {
- new->origin.x= old->origin.x*m[0][0] + old->origin.y*m[1][0] +
- old->origin.z*m[2][0] + m[3][0];
- new->origin.y= old->origin.x*m[0][1] + old->origin.y*m[1][1] +
- old->origin.z*m[2][1] + m[3][1];
- new->origin.z= old->origin.x*m[0][2] + old->origin.y*m[1][2] +
- old->origin.z*m[2][2] + m[3][2];
-
- new->dir.x= old->dir.x*m[0][0] + old->dir.y*m[1][0] + old->dir.z*m[2][0];
- new->dir.y= old->dir.x*m[0][1] + old->dir.y*m[1][1] + old->dir.z*m[2][1];
- new->dir.z= old->dir.x*m[0][2] + old->dir.y*m[1][2] + old->dir.z*m[2][2];
- }
-
- /**********************************************************************/
- /* Transform a plane (not used) */
- /**********************************************************************/
- Plane PlaneTransform(old, m)
- Plane old;
- register Matrix m;
- {
- Plane new;
-
- new.n.x= old.n.x*m[0][0] + old.n.y*m[0][1] + old.n.z*m[0][2];
- new.n.y= old.n.x*m[1][0] + old.n.y*m[1][1] + old.n.z*m[1][2];
- new.n.z= old.n.x*m[2][0] + old.n.y*m[2][1] + old.n.z*m[2][2];
- new.d= old.n.x*m[3][0] + old.n.y*m[3][1] + old.n.z*m[3][2] + old.d;
- return(new);
- }
-
- /**********************************************************************/
- /* Transform a hit -need if transformed the ray for intersection tests*/
- /**********************************************************************/
- void HitTransform(hit, M, iM)
- register HitData *hit; /* Hit data */
- register Matrix M, iM; /* Matrix, and inverse matrix */
- {
- Vector old;
-
- /* Transform intersection point */
- old= hit->intersect;
- hit->intersect.x= old.x*M[0][0] + old.y*M[1][0] + old.z*M[2][0] + M[3][0];
- hit->intersect.y= old.x*M[0][1] + old.y*M[1][1] + old.z*M[2][1] + M[3][1];
- hit->intersect.z= old.x*M[0][2] + old.y*M[1][2] + old.z*M[2][2] + M[3][2];
-
- /* Transform normal at intersection */
- old= hit->normal;
- hit->normal.x= old.x*iM[0][0] + old.y*iM[0][1] + old.z*iM[0][2];
- hit->normal.y= old.x*iM[1][0] + old.y*iM[1][1] + old.z*iM[1][2];
- hit->normal.z= old.x*iM[2][0] + old.y*iM[2][1] + old.z*iM[2][2];
-
- /* Normalize normal */
- if(norm(&hit->normal) < 0.0)
- printf("\tGuess what? HitTransform had a very small normal!!\n");
- }
-
- /**********************************************************************/
- /* Transform a bounding box */
- /**********************************************************************/
- BoundingBoxType BoundingBoxTransform(box, M)
- BoundingBoxType box;
- register Matrix M;
- {
- BoundingBoxType nBox;
- Vector vert[8];
- register int i;
-
- for(i=0;i<8;i++) {
- if(i & 1) vert[i].x= box.max.x;
- else vert[i].x= box.min.x;
- if(i & 2) vert[i].y= box.max.y;
- else vert[i].y= box.min.y;
- if(i & 4) vert[i].z= box.max.z;
- else vert[i].z= box.min.z;
- }
-
- for(i=0;i<8;i++)
- vert[i]= vtransform(vert[i], M);
-
- nBox.min.x= nBox.max.x= vert[0].x;
- nBox.min.y= nBox.max.y= vert[0].y;
- nBox.min.z= nBox.max.z= vert[0].z;
- for(i=1; i<8; i++) {
- if(vert[i].x < nBox.min.x) nBox.min.x= vert[i].x;
- if(vert[i].x > nBox.max.x) nBox.max.x= vert[i].x;
-
- if(vert[i].y < nBox.min.y) nBox.min.y= vert[i].y;
- if(vert[i].y > nBox.max.y) nBox.max.y= vert[i].y;
-
- if(vert[i].z < nBox.min.z) nBox.min.z= vert[i].z;
- if(vert[i].z > nBox.max.z) nBox.max.z= vert[i].z;
- }
-
- /* Make the box a little bit larger */
- nBox.min.x -= VERY_SMALL;
- nBox.max.x += VERY_SMALL;
- nBox.min.y -= VERY_SMALL;
- nBox.max.y += VERY_SMALL;
- nBox.min.z -= VERY_SMALL;
- nBox.max.z += VERY_SMALL;
- return(nBox);
- }
-
- /**********************************************************************/
- /* Initialize ray data */
- /**********************************************************************/
- void RayInit(id, orig, dir, vis, gener, shad, nray)
- long id;
- Vector orig, dir;
- double vis;
- int gener, shad;
- Ray *nray;
- {
- nray->rayID = id;
- nray->origin = orig;
- nray->dir = dir;
- nray->visible = vis;
- nray->generation = gener;
- nray->shadow = shad;
- nray->transmissivity = (Transmit *)NULL;
- }
-
- /**********************************************************************/
- /* Initialize hit data */
- /**********************************************************************/
- void HitInit(dist, inter, text, nrm, nhit)
- double dist;
- Vector inter, text, nrm;
- HitData *nhit;
- {
- nhit->obj = (Objectt *)NULL;
- nhit->poly = (Polygon *)NULL;
- nhit->mesh = (Mesh *)NULL;
- nhit->distance = dist;
- nhit->intersect = inter;
- nhit->texture = text;
- nhit->normal = nrm;
- }
-